package com.moon.game.client;

import java.net.ProtocolException;
import java.util.HashMap;
import java.util.Map;

import org.dom4j.Element;

import com.moon.game.clazz.PBMessageProto.PBMessage;
import com.moon.game.command.RequestSession;
import com.moon.game.config.GlobalConfig;
import com.moon.game.constants.Constants;
import com.moon.game.constants.GlobalConstants;
import com.moon.game.exception.GException;

public class UdpClientSet {
	// DataServer
	private static int dataServerSum = 1;
	private static int profileServerSum = 1;
	private static Map<Integer, UdpClient> dataClientPool = new HashMap<Integer, UdpClient>(); // Data
	private static Map<Integer, UdpClient> profileClientPool = new HashMap<Integer, UdpClient>(); // Data
	private static final String NO_RETURN_MSG = "应传递无返回的PBMessage.";
	private static final String RETURN_MSG = "应传递有返回的PBMessage.";
	private static final String NO_REQUEST_SESSION = "有返回请求时RequestSession不能为null.";

	/**
	 * 根据playerId散列数据服务器
	 * 
	 * @param playerId
	 * @return
	 */
	private static UdpClient getDataClient(String playerId) {
		int index = Math.abs(playerId.hashCode() % dataServerSum);
		return dataClientPool.get(index);
	}
	
	/**
	 * 根据playerId散列数据服务器
	 * 
	 * @param playerId
	 * @return
	 */
	private static UdpClient getProfileClient(String playerId) {
		int index = Math.abs(playerId.hashCode() % profileServerSum);
		return profileClientPool.get(index);
	}
	
	public static void init() {
		// Data初始化
		dataServerSum = GlobalConfig.getDataServerSum();
		for (int i = 0; i < dataServerSum; i++) {
			Element element = GlobalConfig.getDataServer(i);
			String bindip = element.attributeValue("bindip");
			int bindport = Integer.parseInt(element.attributeValue("bindport"));
			UdpClient udpClient = new UdpClient(bindip, bindport, UdpClient.CODEC_PROTOBUF, GlobalConstants.DATA_SERVER_SEND_MAX, GlobalConstants.DATA_SERVER_REC_MAX);
			dataClientPool.put(i, udpClient);
		}
		
		profileServerSum = GlobalConfig.getProfileServerSum();
		for (int i = 0; i < profileServerSum; i++) {
			Element element = GlobalConfig.getProfileServer(i);
			String bindip = element.attributeValue("bindip");
			int bindport = Integer.parseInt(element.attributeValue("bindport"));
			UdpClient udpClient = new UdpClient(bindip, bindport, UdpClient.CODEC_PROTOBUF, GlobalConstants.PROFILE_SERVER_SEND_MAX, GlobalConstants.PROFILE_SERVER_REC_MAX);
			profileClientPool.put(i, udpClient);
		}
	}

	/**
	 * 发送请求给DataServer
	 * 
	 * @param request
	 */
	public static void send2ProfileServer(PBMessage.Builder request) {
		UdpClientSet.getProfileClient(request.getId()).sendNoReturn(request.build());
	}

	/**
	 * 发送请求给ProfileServer
	 * 
	 * @param reqSession
	 * @param request
	 * @param isReutrn
	 */
	public static void send2ProfileServer(RequestSession reqSession, PBMessage.Builder request) throws GException {
		send2ProfileServer(reqSession, request, Constants.TIMEOUT_RETURN);
	}

	/**
	 * 发送请求给ProfileServer
	 * 
	 * @param reqSession
	 * @param request
	 * @param isReturn
	 */
	public static void send2ProfileServer(RequestSession reqSession, PBMessage.Builder request, int reSendFlag) throws GException {
		if (reqSession == null) {
			throw new GException(NO_REQUEST_SESSION);
		}

		if (!request.getIsReturn()) {
			throw new GException(RETURN_MSG);
		}

		UdpClientSet.getProfileClient(request.getId()).send(reqSession, request.build(), reSendFlag);
	}
	
	/**
	 * 发送无返回的请求给ProfileServer
	 * @param request
	 */
	public static void send2ProfileServerNoReturn(PBMessage.Builder request){
		UdpClientSet.getProfileClient(request.getId()).sendNoReturn(request.build());
	}
	
	
	/**
	 * 发送请求给DataServer
	 * 
	 * @param request
	 */
	public static void send2DataServer(PBMessage.Builder request) {
		UdpClientSet.getDataClient(request.getId()).sendNoReturn(request.build());
	}

	/**
	 * 发送请求给DataServer
	 * 
	 * @param reqSession
	 * @param request
	 * @param isReutrn
	 */
	public static void send2DataServer(RequestSession reqSession, PBMessage.Builder request) throws ProtocolException {
		send2DataServer(reqSession, request, Constants.TIMEOUT_RETURN);
	}

	/**
	 * 发送请求给DataServer
	 * 
	 * @param reqSession
	 * @param request
	 * @param isReturn
	 */
	public static void send2DataServer(RequestSession reqSession, PBMessage.Builder request, int reSendFlag) throws ProtocolException {
		if (reqSession == null) {
			throw new ProtocolException(NO_REQUEST_SESSION);
		}

		if (!request.getIsReturn()) {
			throw new ProtocolException(RETURN_MSG);
		}

		UdpClientSet.getDataClient(request.getId()).send(reqSession, request.build(), reSendFlag);
	}
}
